
/******************************************************************************/
/** \file main.c
 **
 ** A detailed description is available at
 ** @link Sample Group Some description @endlink
 **
 **   - 2018-03-09  1.0  Lux First version
 **
 ******************************************************************************/

#include "hc32l136k8ta.h"
#include "system_hc32l136k8ta.h"
#include "sysctrl.h"
#include "ddl.h"
#include "uart.h"
#include "gpio.h"
#include "flash.h"
#include "iap.h"

#include "Ymodem.h"

uint8_t	buff[516];
 
void Sysclk_Config_Init(void);

extern uint32_t	uTick ;

/*使用外部32M时钟*/
void mcu_set_ext_hclk_32Mhz(void)
{ 
	stc_sysctrl_clk_config_t	sysclk_cfg;
	sysclk_cfg.enClkSrc  = SysctrlClkXTH;
	sysclk_cfg.enHClkDiv = SysctrlHclkDiv1;
	sysclk_cfg.enPClkDiv = SysctrlPclkDiv1;
	sysclk_cfg.enFreg.enXTHFreq = SysctrlXthFreq20_32MHz;	
	Sysctrl_ClkInit(&sysclk_cfg);	
}


/*使用内部24M时钟*/
void mcu_set_hclk_24Mhz(void)
{ 
		Sysctrl_SetRCH(SysctrlRchFreq24MHz);
		Sysctrl_SysClkSwitch(SysctrlClkRCH);
		Sysctrl_ClkSourceEnable(SysctrlClkRCL,TRUE);
}

/*****************************************************************************
 * 使用内部或外部时钟，可供选择
 ******************************************************************************/
void Sysclk_Config_Init()
{	

//	mcu_set_ext_hclk_32Mhz();	
  mcu_set_hclk_24Mhz();
	SysTick_Config(SystemCoreClock / 1000U);
	
} 


void Hal_Gpio_Init(void)
{
    stc_gpio_config_t 	stcGpioCfg;

    DDL_ZERO_STRUCT(stcGpioCfg);

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);//

    //PD05=LED 
    stcGpioCfg.enDir = GpioDirOut;
    stcGpioCfg.enDrv = GpioDrvH;
    stcGpioCfg.enOD  = GpioOdDisable;
    stcGpioCfg.enPuPd= GpioPu;
    Gpio_Init(GpioPortD,GpioPin5,&stcGpioCfg);

    //PD04=User key
    stcGpioCfg.enDir = GpioDirIn;
    stcGpioCfg.enDrv = GpioDrvL;
    stcGpioCfg.enOD  = GpioOdDisable;
    stcGpioCfg.enPuPd= GpioPu;
    Gpio_Init(GpioPortD,GpioPin4,&stcGpioCfg);	
}

void _Uart0_Gpio_Init(void)
{
    stc_gpio_config_t 	stcGpioCfg;

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);//
    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);	

    DDL_ZERO_STRUCT(stcGpioCfg);

#if 0
    stcGpioCfg.enDir = GpioDirOut;
    stcGpioCfg.enDrv = GpioDrvH;
    stcGpioCfg.enOD  = GpioOdDisable;
    stcGpioCfg.enPuPd= GpioPu;
    
    Gpio_Init(GpioPortB,GpioPin8,&stcGpioCfg);    
    Gpio_SetAfMode(GpioPortB,GpioPin8,GpioAf7);	//PB8=TX

    stcGpioCfg.enDir = GpioDirIn;
    stcGpioCfg.enDrv = GpioDrvL;
    stcGpioCfg.enOD  = GpioOdEnable;
    stcGpioCfg.enPuPd= GpioPu;
    
    Gpio_Init(GpioPortB,GpioPin9,&stcGpioCfg);
    Gpio_SetAfMode(GpioPortB,GpioPin9,GpioAf7);//PB9=RX

#else

    stcGpioCfg.enDir = GpioDirOut;
    stcGpioCfg.enDrv = GpioDrvH;
    stcGpioCfg.enOD  = GpioOdDisable;
    stcGpioCfg.enPuPd= GpioPu;
    Gpio_Init(GpioPortA,GpioPin9,&stcGpioCfg);
    Gpio_SetAfMode(GpioPortA,GpioPin9,GpioAf1);//TX

    stcGpioCfg.enDir = GpioDirIn;
    stcGpioCfg.enDrv = GpioDrvL;
    stcGpioCfg.enOD  = GpioOdEnable;
    stcGpioCfg.enPuPd = GpioPu;
    Gpio_Init(GpioPortA,GpioPin10,&stcGpioCfg);
    Gpio_SetAfMode(GpioPortA,GpioPin10,GpioAf1);//RX


#endif

}

void Hal_Uart0_Init(void)
{
	stc_uart_config_t	uart_cfg;
	_Uart0_Gpio_Init();
	
	DDL_ZERO_STRUCT(uart_cfg);	
  //UART0 配置   
	uart_cfg.enRunMode = UartMode1;
	uart_cfg.BaudRate.enBaudRate = UART115200;
	uart_cfg.enOver = Uart16Or32Div;
	uart_cfg.enParity = UartDataOrAddr;
	uart_cfg.enStopBit = Uart1bit;
	
	Uart_Init(0,&uart_cfg);
}

 
/**************************************************************************************************
 * 功能描述: 
 **************************************************************************************************/
void Hal_Uart0_Send(uint8_t c)
{
    M0P_UART0->ICR_f.TCCF = 0;
    M0P_UART0->SBUF = c;
    while(M0P_UART0->ISR_f.TC == 0); 
    M0P_UART0->ICR_f.TCCF = 0;
}

void Hal_Uart0_Send_Str(uint8_t *c)
{
    while(*c != '\0')	Hal_Uart0_Send(*c++);
}

uint8_t Hal_Uart0_Recv(uint8_t* c)
{
	uint32_t	tick = HAL_GetSysTick();
	
  while(M0P_UART0->ISR_f.RC == 0)
	{
		if((HAL_GetSysTick() - tick ) > 2)
		{
			return 1;
		}		
	}	
	*c = M0P_UART0->SBUF_f.DATA;
	M0P_UART0->ICR_f.RCCF = 0;
	
	return	0;
}

int hclk = 0;

int main(void)
{
	uint32_t	len;
	uint32_t	timedelay;
	uint8_t		ch;

	Hal_Gpio_Init();
  
	if(Gpio_GetInputIO(GpioPortD,GpioPin4))	//User key not pressed ,jump to app
	{
       iap_load_app(APP_FW_START_ADDR);
	}
		
	Flash_Init(NULL,8,FALSE);	 	
	Flash_WaitCycle(FlashWaitCycle1);	
  
	Sysclk_Config_Init();	

  hclk = Sysctrl_GetHClkFreq(); 
  
	Hal_Gpio_Init();	
	Hal_Uart0_Init();
	
	__enable_irq();
	
	Hal_Uart0_Send_Str("\r\nYmodem(128Byte) Update Start.\r\n");	
  Hal_Uart0_Send_Str("Console input char 'R', then send the bin file to MCU.\r\n");

	timedelay = uTick;
	
	while(1)
	{
		if((uTick - timedelay) > 1000)
		{
			timedelay = uTick; 
			LED_TOG(); /*led toggle*/
		}		
		if(Hal_Uart0_Recv(&ch) == 0)
		{			
			if(ch == 'R')
			{
				YModem_Receive_Proc(buff,&len);
			}else if(ch == 'S')
			{
				YModem_Transmit((uint8_t *)(APP_FW_START_ADDR),"user.bin",1024*40); /* flash读出来用于调试*/
			}else
			{
				Hal_Uart0_Send(ch);				
			}
		}
	}
}



